//
//  ZZCACircleProgress.m
//  ZZCircleProgressDemo
//
//  Created by 周兴 on 2017/7/24.
//  Copyright © 2017年 zhouxing. All rights reserved.
//

#import "ZZCACircleProgress.h"

#define ZZCircleDegreeToRadian(d) ((d)*M_PI)/180.0
#define ZZCircleRGB(r, g, b)      [UIColor colorWithRed: (r)/255.0 green: (g)/255.0 blue: (b)/255.0 alpha: 1.0]
#define ZZCircleSelfWidth  self.frame.size.width
#define ZZCircleSelfHeight self.frame.size.height


@interface ZZCACircleProgress ()<CAAnimationDelegate>

@property (nonatomic, strong) CAShapeLayer *backLayer;
@property (nonatomic, strong) CAShapeLayer *progressLayer;

@property (nonatomic, assign) CGFloat         realWidth;//实际边长
@property (nonatomic, assign) CGFloat         lastProgress;/**<上次进度 0-1 */
@property (nonatomic, strong) CAAnimation     *lastPointAnimation;
@property (nonatomic, strong) CAGradientLayer *gradientLayer;

@end

@implementation ZZCACircleProgress

- (instancetype)init {
    if (self = [super init]) {
        [self initialization];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self initialization];
    }
    return self;
}

- (void)awakeFromNib {
    [super awakeFromNib];
    [self initialization];
    //开始展示
    self.prepareToShow = YES;
}

//初始化
- (instancetype)initWithFrame:(CGRect)frame
                pathBackColor:(UIColor *)pathBackColor
                pathFillColor:(UIColor *)pathFillColor
                   startAngle:(CGFloat)startAngle
                  strokeWidth:(CGFloat)strokeWidth {
    if (self = [super initWithFrame:frame]) {
        [self initialization];
        if (pathBackColor) {
            _pathBackColor = pathBackColor;
        }
        if (pathFillColor) {
            _pathFillColor = pathFillColor;
        }
        _startAngle  = ZZCircleDegreeToRadian(startAngle);
        _strokeWidth = strokeWidth;
    }
    return self;
}

//初始化数据
- (void)initialization {
    self.backgroundColor = [UIColor clearColor];
    _pathBackColor       = ZZCircleRGB(204, 204, 204);
    _pathFillColor       = ZZCircleRGB(219, 184, 102);

    _strokeWidth = 8;//线宽默认为10
    _startAngle  = ZZCircleDegreeToRadian(0);//圆起点位置
    _reduceAngle = ZZCircleDegreeToRadian(0);//整个圆缺少的角度

    _duration         = 0.0;//动画时长
    _showPoint        = YES;//小圆点
    _showProgressText = YES;//文字
    _realWidth        = ZZCircleSelfWidth > ZZCircleSelfHeight ? ZZCircleSelfHeight : ZZCircleSelfWidth;
    _realWidth        = _realWidth-10;
}

#pragma Get
- (CAShapeLayer *)backLayer {
    if (!_backLayer) {
        _backLayer = [CAShapeLayer layer];

        _backLayer.frame = CGRectMake((ZZCircleSelfWidth-_realWidth)/2.0, (ZZCircleSelfHeight-_realWidth)/2.0, _realWidth, _realWidth);

        _backLayer.fillColor   = [UIColor clearColor].CGColor;//填充色
        _backLayer.lineWidth   = _strokeWidth;
        _backLayer.strokeColor = UIColorHEX(0xEFEFF4).CGColor;
        _backLayer.lineCap     = kCALineCapRound;

        UIBezierPath *backCirclePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(_realWidth/2.0, _realWidth/2.0) radius:_realWidth/2.0 startAngle:_startAngle endAngle:(2*M_PI-_reduceAngle+_startAngle) clockwise:YES];
        self.backLayer.path = backCirclePath.CGPath;
    }
    return _backLayer;
}

- (CAShapeLayer *)progressLayer {
    if (!_progressLayer) {
        _progressLayer       = [CAShapeLayer layer];
        _progressLayer.frame = CGRectMake((ZZCircleSelfWidth-_realWidth)/2.0, (ZZCircleSelfHeight-_realWidth)/2.0, _realWidth, _realWidth);

        _progressLayer.fillColor   = [UIColor clearColor].CGColor;//填充色
        _progressLayer.lineWidth   = _strokeWidth;
        _progressLayer.strokeColor = _pathFillColor.CGColor;
        _progressLayer.lineCap     = kCALineCapRound;


        UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(_realWidth/2.0, _realWidth/2.0) radius:_realWidth/2.0 startAngle:_startAngle endAngle:(2*M_PI-_reduceAngle+_startAngle) clockwise:YES];
        _progressLayer.path      = circlePath.CGPath;
        _progressLayer.strokeEnd = 0.0;
    }
    return _progressLayer;
}

- (CAGradientLayer *)gradientLayer {
    if (!_gradientLayer) {
        _gradientLayer            = [[CAGradientLayer alloc] init];
        _gradientLayer.frame      = self.bounds;
        _gradientLayer.colors     = @[(__bridge id)UIColorHEX(0xFCE273).CGColor, (__bridge id)UIColorHEX(0xFF7A00).CGColor];
//        _gradientLayer.startPoint = CGPointMake(0, 0);
//        _gradientLayer.endPoint   = CGPointMake(1, 1);
        _gradientLayer.locations = @[@0.0, @1];
        _gradientLayer.mask       = self.progressLayer;
    }
    return _gradientLayer;
}

- (UIImageView *)pointImage {
    if (!_pointImage) {
        _pointImage = [[UIImageView alloc] init];

        NSBundle *mainBundle      = [NSBundle bundleForClass:[self class]];
        NSBundle *resourcesBundle = [NSBundle bundleWithPath:[mainBundle pathForResource:@"ZZCircleProgress" ofType:@"bundle"]];
        _pointImage.image = [UIImage imageNamed:@"circle_point1" inBundle:resourcesBundle compatibleWithTraitCollection:nil];

        CGFloat realWidth = ZZCircleSelfWidth > ZZCircleSelfHeight ? ZZCircleSelfHeight : ZZCircleSelfWidth;
        _pointImage.frame = CGRectMake(0, 0, _strokeWidth *3, _strokeWidth *3);
        //定位起点位置
        CGPoint shouldPoint = CGPointMake(_realWidth/2.0+(realWidth/2.0)*cosf(_startAngle), _realWidth/2.0+(realWidth/2.0)*sinf(_startAngle));
        _pointImage.center = shouldPoint;
    }
    return _pointImage;
}

- (ZZCountingLabel *)progressLabel {
    if (!_progressLabel) {
        _progressLabel               = [[ZZCountingLabel alloc] init];
        _progressLabel.textColor     = [UIColor blackColor];
        _progressLabel.textAlignment = NSTextAlignmentCenter;
        _progressLabel.font          = [UIFont systemFontOfSize:22];
        _progressLabel.text          = @"0%";
        _progressLabel.frame         = CGRectMake(0, 0, ZZCircleSelfWidth, ZZCircleSelfHeight);
    }
    return _progressLabel;
}

- (UILabel *)ValueLabel {
    if (!_ValueLabel) {
        _ValueLabel               = [[ZZCountingLabel alloc] init];
        _ValueLabel.textColor     = [UIColor whiteColor];
        _ValueLabel.textAlignment = NSTextAlignmentCenter;
        _ValueLabel.font          = SNFONT(40);
        _ValueLabel.text          = @"0";
        _ValueLabel.textColor     = SNCOLORBLACK;
        _ValueLabel.frame         = CGRectMake(0, -5, ZZCircleSelfWidth, ZZCircleSelfHeight);
    }
    return _ValueLabel;
}

- (UILabel *)unitLabel {
    if (!_unitLabel) {
        _unitLabel               = [[ZZCountingLabel alloc] init];
        _unitLabel.textColor     = [UIColor whiteColor];
        _unitLabel.textAlignment = NSTextAlignmentCenter;
        _unitLabel.font          = SNFONT(15);
        _unitLabel.text          = SN_Text(@"步");
        _unitLabel.textColor     = SNCOLORGRAY;
        _unitLabel.frame         = CGRectMake(0, +23, ZZCircleSelfWidth, ZZCircleSelfHeight);
    }
    return _unitLabel;
}

#pragma Set
- (void)setStartAngle:(CGFloat)startAngle {
    if (_startAngle != ZZCircleDegreeToRadian(startAngle)) {
        _startAngle = ZZCircleDegreeToRadian(startAngle);
    }
}

- (void)setReduceAngle:(CGFloat)reduceAngle {
    if (_reduceAngle != ZZCircleDegreeToRadian(reduceAngle)) {
        if (reduceAngle >= 360) {
            return;
        }
        _reduceAngle = ZZCircleDegreeToRadian(reduceAngle);
    }
}

- (void)setStrokeWidth:(CGFloat)strokeWidth {
    if (_strokeWidth != strokeWidth) {
        _strokeWidth = strokeWidth;
    }
}

- (void)setPathBackColor:(UIColor *)pathBackColor {
    if (_pathBackColor != pathBackColor) {
        _pathBackColor             = pathBackColor;
        self.backLayer.strokeColor = _pathBackColor.CGColor;;
    }
}

- (void)setPathFillColor:(UIColor *)pathFillColor {
    if (_pathFillColor != pathFillColor) {
        _pathFillColor                 = pathFillColor;
        self.progressLayer.strokeColor = _pathFillColor.CGColor;
    }
}

- (void)setShowPoint:(BOOL)showPoint {
    if (_showPoint != showPoint) {
        _showPoint = showPoint;
        if (_showPoint) {
            self.pointImage.hidden = NO;
        } else {
            self.pointImage.hidden = YES;
        }
    }
}

- (void)setShowProgressText:(BOOL)showProgressText {
    if (_showProgressText != showProgressText) {
        _showProgressText = showProgressText;
        if (_showProgressText) {
            self.progressLabel.hidden = NO;
        } else {
            self.progressLabel.hidden = YES;
        }
    }
}

- (void)setPrepareToShow:(BOOL)prepareToShow {
    if (_prepareToShow != prepareToShow) {
        _prepareToShow = prepareToShow;
        if (_prepareToShow) {
            [self initSubviews];
        }
    }
}

- (void)setProgress:(CGFloat)progress {
    //准备好显示
    self.prepareToShow = YES;

    _progress = progress;
    if (_progress < 0) {
        _progress = 0;
    }
    if (_progress > 1) {
        _progress = 1;
    }

    [self startAnimation];
}

- (void)startAnimation {
    //线条动画
    CABasicAnimation *pathAnima = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];

    pathAnima.duration = _duration;
//    pathAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    pathAnima.fromValue           = [NSNumber numberWithFloat:_increaseFromLast == YES ? _lastProgress : 0];
    pathAnima.toValue             = [NSNumber numberWithFloat:_progress];
    pathAnima.fillMode            = kCAFillModeForwards;
    pathAnima.removedOnCompletion = NO;
    [self.progressLayer addAnimation:pathAnima forKey:@"strokeEndAnimation"];

    if (_showPoint) {
        //小图片动画
        CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        pathAnimation.timingFunction      = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
        pathAnimation.fillMode            = kCAFillModeForwards;
        pathAnimation.calculationMode     = @"paced";
        pathAnimation.removedOnCompletion = NO;
        pathAnimation.duration            = _duration;
        pathAnimation.delegate            = self;
        CGMutablePathRef curvedPath = CGPathCreateMutable();
        BOOL             shouldNot  = NO;
        if (_progress < _lastProgress && _increaseFromLast == YES) {
            shouldNot = YES;
        }
        CGPathAddArc(curvedPath, NULL, _realWidth/2.0, _realWidth/2.0, _realWidth/2.0, _increaseFromLast == YES ? (2*M_PI-_reduceAngle)*_lastProgress+_startAngle : _startAngle, (2*M_PI-_reduceAngle)*_progress+_startAngle, shouldNot);
        pathAnimation.path = curvedPath;
        CGPathRelease(curvedPath);
        [self.pointImage.layer addAnimation:pathAnimation forKey:nil];
        self.lastPointAnimation = pathAnimation;
        if (!_increaseFromLast && _progress == 0.0) {
            [self.pointImage.layer removeAllAnimations];
        }
    }

    if (_showProgressText) {
        if (_increaseFromLast) {
            [self.progressLabel countingFrom:_lastProgress*100 to:_progress*100 duration:_duration];
        } else {
            [self.progressLabel countingFrom:0 to:_progress*100 duration:_duration];
        }
    }


    _lastProgress = _progress;
}

//监听动画结束
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    [self updatePointPosition];
}

//更新小圆点的真实位置
- (void)updatePointPosition {
    //重定位起点
    CGFloat progress = _progress;

    if (isnan(progress)) {
        progress = 0.0;
    }
    //重定位起点
    CGFloat currentEndAngle = (2*M_PI-_reduceAngle)*progress+_startAngle;
    [_pointImage.layer removeAllAnimations];
    _pointImage.center = CGPointMake(_realWidth/2.0+_realWidth/2.0*cosf(currentEndAngle), _realWidth/2.0+_realWidth/2.0*sinf(currentEndAngle));
}

- (void)initSubviews {
    [self.layer addSublayer:self.backLayer];
    [self.layer addSublayer:self.progressLayer];

    
    
    //创建渐变层
    [self.layer addSublayer:self.gradientLayer];

//    [self addSubview:self.pointImage];
    [self addSubview:self.ValueLabel];
    [self addSubview:self.unitLabel];
//    [self addSubview:self.progressLabel];
}

@end
